/*
 * 雪花算法
 * 参考文档：https://www.jianshu.com/p/20d4db1aa790
 */
// 二进制补位
const binaryCover = (
  str: string | number | bigint,
  digit: number
): string | boolean => {
  str = str.toString(2).toString();
  const len = str.length;
  for (let i = 0; i < digit - len; i++) {
    str = "0" + str;
  }
  return str;
};
export class SnowFlake {
  baseTimeStmap = Date.now();
  // 机器id
  deviceId: number;
  // 最后一次时间戳
  lastTimeStmap: number;
  // 序列号
  serialNumber = 1;
  constructor(deviceId: number) {
    this.deviceId = deviceId;
  }
  getnextId() {
    const timeStmap = Date.now() - this.baseTimeStmap;
    // 同一毫秒序列号+1
    if (timeStmap == this.lastTimeStmap) {
      this.serialNumber++;
    } else {
      this.lastTimeStmap = timeStmap;
      this.serialNumber = 1;
    }
    const timeBinary = binaryCover(timeStmap, 41);
    const deviceBinary = binaryCover(this.deviceId, 10);
    const serialNumberBinary = binaryCover(this.serialNumber, 12);
    const id = BigInt(`0b1${timeBinary}${deviceBinary}${serialNumberBinary}`);
    return id.toString(10);
  }
}
const snowflake = new SnowFlake(1001);
export const generateId = () => {
  return snowflake.getnextId();
};
